package com.yanqu.road.server.manger.kuang;

import com.yanqu.road.entity.config.system.NormalWeightItem;
import com.yanqu.road.entity.config.system.PropertyWeightItem;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.enums.eRankType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.enums.kuang.eKuangAttributeType;
import com.yanqu.road.entity.kuang.KuangConfig;
import com.yanqu.road.entity.kuang.KuangEquipmentData;
import com.yanqu.road.entity.kuang.KuangRankRewardConfig;
import com.yanqu.road.entity.kuang.config.KuangEquipmentConfig;
import com.yanqu.road.entity.kuang.config.KuangSystemConfig;
import com.yanqu.road.entity.kuang.config.entity.KuangTimeConfig;
import com.yanqu.road.entity.kuang.group.KuangMatchGroup;
import com.yanqu.road.entity.servercenter.ChannelSystemConfig;
import com.yanqu.road.logic.bussiness.kuang.KuangBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.logic.rank.RankListModel;
import com.yanqu.road.pb.kuang.Kuang;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.kuang.KuangModule;
import com.yanqu.road.server.manger.ChannelSystemConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.system.GameChannelSystemConfigMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 矿场争夺战
 */
public class KuangMgr extends TempMgr {

    /**
     * 匹配分组，有分组才能进入活动战斗
     */
    private static KuangMatchGroup group = null;

    private static KuangConfig config = null;

    private static RandomHelper randomHelper = new RandomHelper();


    public static void syncMatchGroup(KuangMatchGroup matchGroup) throws Exception {
        if (matchGroup == null) {
            return;
        }
        if (group == null || (
                group.getWeekId() != matchGroup.getWeekId()
                || group.getGroupId() != matchGroup.getGroupId()
                || group.getCrossId() != matchGroup.getCrossId()
        )) {
            // 刷一下配置
            try {
                reloadKuangConfig();
            } catch (Exception e) {
                getLogger().error("reloadKuangConfig error:", e);
                return;
            }

            // 配置刷完再更新分组防止 配置出问题
            group = matchGroup;
            getLogger().info("syncMatchGroup success, groupId:{},!!!", group.getGroupId());
            // 同步下在线用户
            for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
                gamePlayer.getModule(KuangModule.class).initSystem();
            }
        }
    }

    public static KuangMatchGroup getMatchGroup() {
        checkGroup();
        return group;
    }

    public static int getMatchGroupId() {
        checkGroup();
        return group == null ? -1 : group.getGroupId();
    }

    /**
     * 检查是否跨周
     */
    public static void checkGroup() {
        int weekId = GameConfig.getSystemThisWeekId();
        if (group != null && weekId != group.getWeekId()) {
            group = null;
        }
    }

    @Override
    public boolean init() throws Exception {
        addManagerReloadListener();
        return reload();
    }

    public void addManagerReloadListener() {
        ChannelSystemConfigMgr.addReloadListener(() -> {
            reloadKuangConfig();
            getLogger().info("KuangMgr addManagerReloadListener");
        });
    }

    public static void reloadKuangConfig() {
        // 加载后台配置
        int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
        Map<String, ChannelSystemConfig> systemConfigMap = GameChannelSystemConfigMgr.getSystemConfigMap(channelId, eSystemId.Kuang.getValue());
        if (systemConfigMap == null) {
            getLogger().error("矿场配置未加载");
            return;
        }
        KuangConfig kuangConfig = new KuangConfig();
        kuangConfig.setEquipmentConfigMap(KuangBusiness.getKuangEquipmentConfigMap());

        // 装备抽取权重
        Map<Integer, List<NormalWeightItem>> equipmentQualityWeightListMap = new ConcurrentHashMap<>();
        List<String> qualityWeightList = StringUtils.stringToStringList(GameConfig.KUANG_EQUIPMENT_LV, "\\|");
        for (String qualityWeight : qualityWeightList) {
            List<Integer> list = StringUtils.stringToIntegerList(qualityWeight, ";");
            List<NormalWeightItem> weightItemList = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                if (i == 0) {
                    // 第一个是天数
                    continue;
                }
                Integer weight = list.get(i);
                weightItemList.add(new NormalWeightItem(BigInteger.valueOf(i), weight));
            }
            equipmentQualityWeightListMap.put(list.get(0), weightItemList);
        }
        kuangConfig.setEquipmentQualityWeightListMap(equipmentQualityWeightListMap);

        // 最大属性值
        Map<eKuangAttributeType, Long> maxAttributeMap = new ConcurrentHashMap<>();
        List<String> maxAttributeList = StringUtils.stringToStringList(GameConfig.KUANG_ATTRIBUTE_VALUE_MAX, "\\|");
        for (String s : maxAttributeList) {
            String[] split = s.split("=");
            maxAttributeMap.put(eKuangAttributeType.forValue(Integer.parseInt(split[0])), Long.valueOf(split[1]));
        }
        kuangConfig.setMaxAttributeMap(maxAttributeMap);

        // 战力计算参数
        kuangConfig.setAbilityParamList(StringUtils.stringToIntegerList(GameConfig.KUANG_XIANLI_PRM, "\\|"));


        // 争夺战时间
        // 矿场争夺战开启自动报名时间|活动准备期开始时间|开战前准备期时间|活动开始时间|领奖期开始|领奖期结束时间（按星期，配置分钟，星期一零点为0）
        List<Long> kuangTimeList = StringUtils.stringToLongList(GameConfig.KUANG_TIME, "\\|");
        long weekStartTime = DateHelper.getThisWeekStartTime(GameConfig.DAY_SYSTEM_RESET_TIME);
        // 矿场争夺战开启自动报名时间
        KuangTimeConfig timeConfig = new KuangTimeConfig();
        // 时间需要减掉前几天
        weekStartTime = weekStartTime - (GameConfig.DAY_SYSTEM_RESET_TIME - 1) * DateHelper.DAY_MILLIONS;
        // 展示期开始时间/开启自动报名时间
        timeConfig.setBeginShowTime(weekStartTime + kuangTimeList.get(0) * 60L * 1000L);
        // 首日活动打造装备准备期开始时间
        timeConfig.setDay1BeginTime(weekStartTime + kuangTimeList.get(1) * 60L * 1000L);
        // 首日开战前准备期时间
        timeConfig.setDay1BattlePrepareTime(weekStartTime + kuangTimeList.get(2) * 60L * 1000L);
        // 首日活动战斗开始时间
        timeConfig.setDay1BattleStartTime(weekStartTime + kuangTimeList.get(3) * 60L * 1000L);
        // 首日活动战斗结束时间
        timeConfig.setDay1BattleEndTime(weekStartTime + kuangTimeList.get(4) * 60L * 1000L);
        // 次日活动打造装备准备期开始时间
        timeConfig.setDay2BeginTime(weekStartTime + kuangTimeList.get(5) * 60L * 1000L);
        // 次日开战前准备期时间
        timeConfig.setDay2BattlePrepareTime(weekStartTime + kuangTimeList.get(6) * 60L * 1000L);
        // 次日活动战斗开始时间
        timeConfig.setDay2BattleStartTime(weekStartTime + kuangTimeList.get(7) * 60L * 1000L);
        // 次日活动战斗结束时间/领奖期开始
        timeConfig.setDay2BattleEndTime(weekStartTime + kuangTimeList.get(8) * 60L * 1000L);
        // 领奖期结束时间
        timeConfig.setRewardEndTime(weekStartTime + kuangTimeList.get(9) * 60L * 1000L);
        kuangConfig.setTimeConfig(timeConfig);


        KuangSystemConfig kuangSystemConfig = new KuangSystemConfig();
        // 矿场消耗
        ChannelSystemConfig kuangshanLotteryCost = systemConfigMap.get("KUANGSHAN_LOTTERY_COST");
        if (kuangshanLotteryCost == null) {
            getLogger().error("矿场配置KUANGSHAN_LOTTERY_COST未加载");
            return;
        }
        kuangSystemConfig.setLotteryCost(PropertyHelper.parseStringToProperty(kuangshanLotteryCost.getValue()));
        // 矿场宝库数量
        ChannelSystemConfig kuangshanLotteryBoxNum = systemConfigMap.get("KUANGSHAN_LOTTERY_BOX_NUM");
        if (kuangshanLotteryBoxNum == null) {
            getLogger().error("矿场配置KUANGSHAN_LOTTERY_BOX_NUM未加载");
            return;
        }
        kuangSystemConfig.setLotteryBoxNum(Integer.parseInt(kuangshanLotteryBoxNum.getValue()));
        // 个人战绩排行榜奖励
        ChannelSystemConfig kuangshanRewardPerson = systemConfigMap.get("KUANGSHAN_REWARD_PERSON");
        if (kuangshanRewardPerson == null) {
            getLogger().error("矿场配置KUANGSHAN_REWARD_PERSON未加载");
            return ;
        }
        String rewardPerson = kuangshanRewardPerson.getValue();
        Map<Integer, List<KuangRankRewardConfig>> personRankRewardMap = new ConcurrentHashMap<>();
        List<String> person1 = StringUtils.stringToStringList(rewardPerson, "\\|");
        for (String person2 : person1) {
            String[] split = person2.split(":");
            int openDay = Integer.parseInt(split[0]);
            List<KuangRankRewardConfig> list = new ArrayList<>();
            String person3 = split[1];
            String[] split1 = person3.split("#");
            for (String person4 : split1) {
                KuangRankRewardConfig rankRewardConfig = new KuangRankRewardConfig();
                String[] split2 = person4.split("-");
                int minRank = Integer.parseInt(split2[0]);
                int maxRank = Integer.parseInt(split2[1]);
                String person5 = split2[2];
                rankRewardConfig.setMinRank(minRank);
                rankRewardConfig.setMaxRank(maxRank);
                rankRewardConfig.setReward(person5);
                list.add(rankRewardConfig);
            }
            personRankRewardMap.put(openDay, list);
        }
        kuangSystemConfig.setPersonRankRewardConfigMap(personRankRewardMap);
        // 阵营积分榜奖励配置
        ChannelSystemConfig kuangshanRewardGroup = systemConfigMap.get("KUANGSHAN_REWARD_GROUP");
        if (kuangshanRewardGroup == null) {
            getLogger().error("矿场配置KUANGSHAN_REWARD_GROUP未加载");
            return;
        }
        String rewardGroup = kuangshanRewardGroup.getValue();
        Map<Integer, List<KuangRankRewardConfig>> groupRankRewardMap = new ConcurrentHashMap<>();
        List<String> group1 = StringUtils.stringToStringList(rewardGroup, "\\|");
        for (String group2 : group1) {
            String[] split = group2.split(":");
            int openDay = Integer.parseInt(split[0]);
            List<KuangRankRewardConfig> list = new ArrayList<>();
            String group3 = split[1];
            String[] split1 = group3.split("#");
            for (String group4 : split1) {
                KuangRankRewardConfig rankRewardConfig = new KuangRankRewardConfig();
                String[] split2 = group4.split("-");
                int minRank = Integer.parseInt(split2[0]);
                int maxRank = Integer.parseInt(split2[1]);
                String group5 = split2[2];
                rankRewardConfig.setMinRank(minRank);
                rankRewardConfig.setMaxRank(maxRank);
                rankRewardConfig.setReward(group5);
                list.add(rankRewardConfig);
            }
            groupRankRewardMap.put(openDay, list);
        }
        kuangSystemConfig.setGroupRankRewardConfigMap(groupRankRewardMap);
        // 矿山-宝库普通奖励
        Map<Integer, List<PropertyWeightItem>> lotteryGeneraReward = new ConcurrentHashMap<>();
        ChannelSystemConfig kuangshanLotteryGenera = systemConfigMap.get("KUANGSHAN_LOTTERY_GENERAL");
        if (kuangshanLotteryGenera == null) {
            getLogger().error("矿场配置KUANGSHAN_LOTTERY_GENERAL未加载");
            return;
        }
        String lotteryGenera = kuangshanLotteryGenera.getValue();
        List<String> genera1 = StringUtils.stringToStringList(lotteryGenera, "\\|");
        for (String genera2 : genera1) {
            String[] split = genera2.split(":");
            int openDay = Integer.parseInt(split[0]);
            String genera3 = split[1];
            List<PropertyWeightItem> list = new ArrayList<>();
            List<String> genera4 = StringUtils.stringToStringList(genera3, ";");
            for (String genera5 : genera4) {
                PropertyWeightItem propertyWeightItem = new PropertyWeightItem();
                List<Integer> genera6 = StringUtils.stringToIntegerList(genera5, "=");
                propertyWeightItem.setProperty(new Property(genera6.get(0), genera6.get(1)));
                propertyWeightItem.setWeight(genera6.get(2));
                list.add(propertyWeightItem);
            }
            lotteryGeneraReward.put(openDay, list);
        }
        kuangSystemConfig.setLotteryGeneraRewardMap(lotteryGeneraReward);
        // 矿山-宝库大奖奖励
        Map<Integer, List<PropertyWeightItem>> lotterySpecialReward = new ConcurrentHashMap<>();
        ChannelSystemConfig kuangshanLotterySpecial = systemConfigMap.get("KUANGSHAN_LOTTERY_SPECIAL");
        if (kuangshanLotterySpecial == null) {
            getLogger().error("矿场配置KUANGSHAN_LOTTERY_SPECIAL未加载");
            return;
        }
        String lotterySpecial = kuangshanLotterySpecial.getValue();
        List<String> special1 = StringUtils.stringToStringList(lotterySpecial, "\\|");
        for (String special2 : special1) {
            String[] split = special2.split(":");
            int openDay = Integer.parseInt(split[0]);
            String special3 = split[1];
            List<PropertyWeightItem> list = new ArrayList<>();
            List<String> special4 = StringUtils.stringToStringList(special3, ";");
            for (String special5 : special4) {
                PropertyWeightItem propertyWeightItem = new PropertyWeightItem();
                List<Integer> special6 = StringUtils.stringToIntegerList(special5, "=");
                propertyWeightItem.setProperty(new Property(special6.get(0), special6.get(1)));
                propertyWeightItem.setWeight(special6.get(2));
                list.add(propertyWeightItem);
            }
            lotterySpecialReward.put(openDay, list);
        }
        kuangSystemConfig.setLotterySpecialRewardMap(lotterySpecialReward);
        kuangConfig.setKuangSystemConfig(kuangSystemConfig);

        config = kuangConfig;
    }


    @Override
    public boolean reloadConfig() throws Exception {
        reloadKuangConfig();
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    /**
     * 抽取装备品质
     */
    public static int drawQuality(int totalDrawTimes) {
        if (config == null) {
            return -1;
        }
        NormalWeightItem randomResult = WeightHelper.getRandomResult(getEquipmentQualityWeightList(totalDrawTimes));
        return randomResult == null ? -1 : randomResult.getValue().intValue();
    }

    /**
     * 根据抽取次数获取权重
     */
    public static List<NormalWeightItem> getEquipmentQualityWeightList(int totalDrawTimes) {
        List<NormalWeightItem> list = new ArrayList<>();
        int maxTotalDrawTimes = Integer.MIN_VALUE;
        for (Map.Entry<Integer, List<NormalWeightItem>> entry : config.getEquipmentQualityWeightListMap().entrySet()) {
            Integer drawTimes = entry.getKey();
            if (totalDrawTimes >= drawTimes && drawTimes >= maxTotalDrawTimes) {
                maxTotalDrawTimes = drawTimes;
                list = entry.getValue();
            }
        }
        return list;
    }

    /**
     * 根据品质抽一个装备
     *
     * @param quality 品质
     */
    public static int drawEquip(int quality) {
        List<Integer> equipList = new ArrayList<>();
        for (KuangEquipmentConfig equipmentConfig : config.getEquipmentConfigMap().values()) {
            if (equipmentConfig.getQuality() == quality) {
                equipList.add(equipmentConfig.getId());
            }
        }
        if (equipList.size() == 0) {
            return -1;
        }
        return equipList.get(randomHelper.next(0, equipList.size()));
    }

    /**
     * 初始化装备
     *
     * @param equipId 装备id
     */
    public static KuangEquipmentData initEquipmentData(int equipId) {
        KuangEquipmentConfig equipmentConfig = config.getEquipmentConfig(equipId);
        if (equipmentConfig == null) {
            getLogger().error("config not found!!!");
            return null;
        }
        KuangEquipmentData equipmentData = new KuangEquipmentData();
        equipmentData.setEquipmentId(equipId);
        equipmentData.setType(equipmentConfig.getType());
        // 基础属性
        String attribute = equipmentConfig.getAttribute();
        if (!StringUtils.isNullOrEmpty(attribute) && !attribute.equals("0")) {
            List<String> attributeList = StringUtils.stringToStringList(attribute, "\\|");
            for (String attributeParam : attributeList) {
                String[] split = attributeParam.split("=");
                int attributeId = Integer.parseInt(split[0]);
                String[] split1 = split[1].split(";");
                int minValue = Integer.parseInt(split1[0]);
                int maxValue = Integer.parseInt(split1[1]);
                eKuangAttributeType attributeType = com.yanqu.road.entity.enums.kuang.eKuangAttributeType.forValue(attributeId);
                if (attributeType == null) {
                    // 未知属性
                    continue;
                }
                equipmentData.getAttributeMap().put(attributeType, equipmentData.getAttributeMap().getOrDefault(attributeType, 0L) + randomHelper.next(minValue, maxValue + 1));
            }
        }
        // 固有属性
        String fixAttribute = equipmentConfig.getFixAttribute();
        if (!StringUtils.isNullOrEmpty(fixAttribute)) {
            String[] split = fixAttribute.split("#");
            // 可随机属性条数
            String randomParam = split[0];
            String[] split1 = randomParam.split(";");
            int randomCnt = randomHelper.next(Integer.parseInt(split1[0]), Integer.parseInt(split1[1]) + 1);
            List<String> attributeParamList = StringUtils.stringToStringList(split[1], "\\|");
            Collections.shuffle(attributeParamList);
            while (randomCnt-- > 0 && attributeParamList.size() > 0) {
                String attributeParam = attributeParamList.remove(0);
                String[] split2 = attributeParam.split("=");
                int attributeId = Integer.parseInt(split2[0]);
                String[] split3 = split2[1].split(";");
                int minValue = Integer.parseInt(split3[0]);
                int maxValue = Integer.parseInt(split3[1]);
                eKuangAttributeType attributeType = com.yanqu.road.entity.enums.kuang.eKuangAttributeType.forValue(attributeId);
                if (attributeType == null) {
                    // 未知属性
                    continue;
                }
                equipmentData.getFixAttributeMap().put(attributeType, equipmentData.getFixAttributeMap().getOrDefault(attributeType, 0L) + randomHelper.next(minValue, maxValue + 1));
            }
        }
        // 进阶属性
        String advancedAttribute = equipmentConfig.getAdvancedAttribute();
        if (!StringUtils.isNullOrEmpty(advancedAttribute)) {
            String[] split = advancedAttribute.split("#");
            // 可随机属性条数
            String randomParam = split[0];
            String[] split1 = randomParam.split(";");
            int randomCnt = randomHelper.next(Integer.parseInt(split1[0]), Integer.parseInt(split1[1]) + 1);
            List<String> attributeParamList = StringUtils.stringToStringList(split[1], "\\|");
            Collections.shuffle(attributeParamList);
            while (randomCnt-- > 0 && attributeParamList.size() > 0) {
                String attributeParam = attributeParamList.remove(0);
                String[] split2 = attributeParam.split("=");
                int attributeId = Integer.parseInt(split2[0]);
                String[] split3 = split2[1].split(";");
                int minValue = Integer.parseInt(split3[0]);
                int maxValue = Integer.parseInt(split3[1]);
                eKuangAttributeType attributeType = com.yanqu.road.entity.enums.kuang.eKuangAttributeType.forValue(attributeId);
                if (attributeType == null) {
                    // 未知属性
                    continue;
                }
                equipmentData.getAdvancedAttributeMap().put(attributeType, equipmentData.getAdvancedAttributeMap().getOrDefault(attributeType, 0L) + randomHelper.next(minValue, maxValue + 1));
            }
        }
        // 计算装备总属性
        for (Map.Entry<eKuangAttributeType, Long> entry : equipmentData.getAttributeMap().entrySet()) {
            equipmentData.getTotalAttributeMap().put(entry.getKey(), equipmentData.getTotalAttributeMap().getOrDefault(entry.getKey(), 0L) + entry.getValue());
        }
        for (Map.Entry<eKuangAttributeType, Long> entry : equipmentData.getFixAttributeMap().entrySet()) {
            equipmentData.getTotalAttributeMap().put(entry.getKey(), equipmentData.getTotalAttributeMap().getOrDefault(entry.getKey(), 0L) + entry.getValue());
        }
        for (Map.Entry<eKuangAttributeType, Long> entry : equipmentData.getAdvancedAttributeMap().entrySet()) {
            equipmentData.getTotalAttributeMap().put(entry.getKey(), equipmentData.getTotalAttributeMap().getOrDefault(entry.getKey(), 0L) + entry.getValue());
        }
        // 装备评分
        List<Integer> paramList = config.getAbilityParamList();
        long score = BigDecimal.valueOf(paramList.get(6)).divide(BigDecimal.valueOf(1000000), 10, RoundingMode.UP).multiply(
                BigDecimal.valueOf(equipmentData.getTotalAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Critical, 0L)).multiply(BigDecimal.valueOf(paramList.get(0)))
                        .add(BigDecimal.valueOf(equipmentData.getTotalAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Toughness, 0L)).multiply(BigDecimal.valueOf(paramList.get(1))))
                        .add(BigDecimal.valueOf(equipmentData.getTotalAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_AttackSpeed, 0L)).multiply(BigDecimal.valueOf(paramList.get(2))))
                        .add(BigDecimal.valueOf(equipmentData.getTotalAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Dodge, 0L)).multiply(BigDecimal.valueOf(paramList.get(3))))
                        .add(BigDecimal.valueOf(equipmentData.getTotalAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Hit, 0L)).multiply(BigDecimal.valueOf(paramList.get(4))))
                        .add(BigDecimal.valueOf(equipmentData.getTotalAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_LifeSteal, 0L)).multiply(BigDecimal.valueOf(paramList.get(5))))
        ).setScale(0, RoundingMode.UP).longValue();
        equipmentData.getTotalAttributeMap().put(eKuangAttributeType.AttributeEnum_EquipmentScore, score);
        return equipmentData;

    }

    public static KuangConfig getConfig() {
        return config;
    }



    public static void offLine(GamePlayer player) {
        KuangMatchGroup matchGroup = getMatchGroup();
        if (matchGroup == null) {
            return;
        }
        // 离线通知跨服
        Kuang.CrossKuangOffLineReqMsg.Builder reqMsg = Kuang.CrossKuangOffLineReqMsg.newBuilder();
        reqMsg.setGroupId(matchGroup.getGroupId());
        player.getModule(KuangModule.class).sendAppointActivityPacket(Protocol.C_CROSS_KUANG_OFF_LINE, reqMsg);

        // 离线时如果数据还没同步也上传一下
        if (needUploadUserIds.contains(player.getUserId())) {
            synchronized (needUploadUserIds) {
                needUploadUserIds.remove(player.getUserId());
            }
            player.getModule(KuangModule.class).uploadAttributeToCross();
        }
    }

    /**
     * 获取最大抽取次数
     */
    public static int getMaxDrawTimes(int roundDay) {
        if (roundDay == 0) {
            return 0;
        }
        List<Integer> list = StringUtils.stringToIntegerList(GameConfig.KUANG_EQUIPMENT_DRAW_NUM, "\\|");
        if (roundDay == 1) {
            return list.get(0);
        } else if (roundDay == 2) {
            return list.get(1);
        }
        return 0;
    }

    public static void getPatronsAbilityUserRankByCmd(long originUserId) {
        if (group == null) {
            return;
        }
        Kuang.CrossKuangUserAbilityRankListRespMsg.Builder builder = Kuang.CrossKuangUserAbilityRankListRespMsg.newBuilder();
        builder.setOriginUserId(originUserId);
        RankProto.RankListMsg.Builder rankListMsg;
        // 本服赚钱榜
        RankListModel rankListModel = RankMgr.getRankListModelByType(eBigRankType.Normal.getValue(), eRankType.PatronsAbility.getValue());
        if (null != rankListModel) {
            rankListMsg = rankListModel.getRankListMsg();
            builder.setMyRank(rankListModel.unlockGetMyRank(originUserId));
        } else {
            rankListMsg = RankProto.RankListMsg.newBuilder();
            builder.setMyRank(-1);
        }
        builder.setRankList(rankListMsg);
        builder.setGroupId(group.getGroupId());
        // 回活动服
        GamePlayerMgr.sendAppointActivityPacket(Protocol.C_CROSS_KUANG_GET_USER_ABILITY_RESULT, builder, 0, group.getCrossId());
    }

    /**
     * 需要上传属性的用户id
     */
    private static Set<Long> needUploadUserIds= new HashSet<>();

    /**
     * 定时上传用户属性
     */
    public static void uploadAttributeTask() {
        List<Long> list = new ArrayList<>();
        synchronized (needUploadUserIds) {
            list.addAll(new ArrayList<>(needUploadUserIds));
            needUploadUserIds.clear();
        }
        for (Long userId : list) {
            GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(userId);
            if (onlinePlayer != null) {
                // 上传属性到跨服
                onlinePlayer.getModule(KuangModule.class).uploadAttributeToCross();
            }
        }
    }

    public static void addUploadAttributeUserId(long userId) {
        synchronized (needUploadUserIds) {
            needUploadUserIds.add(userId);
        }
    }


}
